/**
 * 前端API接口封装模块
 * 
 * 主要功能：
 * 1. 封装所有后端API接口调用
 * 2. 统一处理HTTP请求（Fetch API）
 * 3. 自动携带JWT Token认证
 * 4. 统一错误处理和中文提示
 * 5. 提供模块化的API调用方式
 * 
 * 使用方式：
 * const api = new API();
 * const result = await api.auth.login('username', 'password');
 * const books = await api.books.getList();
 * 
 * 设计模式：
 * - 单例模式：全局只创建一个API实例
 * - 模块化：按功能分组（auth、books、records等）
 * - 面向对象：使用class封装
 * 
 * @author 个人预算管理系统开发团队
 * @date 2025-10-26
 */

// ==================== 配置常量 ====================

/**
 * API基础URL
 * 
 * 开发环境：http://localhost:3000/api
 * 生产环境：需修改为实际域名，如：https://budget.example.com/api
 * 
 * 部署提示：
 * 部署到服务器前，需将此地址改为线上地址
 */
const API_BASE_URL = 'http://localhost:3000/api';

// ==================== API类定义 ====================

/**
 * API接口封装类
 * 
 * @class APIClient
 * @description 封装所有后端API接口，提供统一的调用方式
 */
class APIClient {
    /**
     * 构造函数
     * 
     * @constructor
     * @description 初始化API实例
     * 
     * 设计考虑：
     * 不在构造函数中读取token，而是每次请求时动态读取
     * 原因：token可能在运行时更新（如重新登录），动态读取确保使用最新值
     */
    constructor() {
        // 不在构造函数中读取 token，而是每次请求时动态读取
    }

    // ==================== Token管理方法 ====================

    /**
     * 获取当前Token
     * 
     * @method getToken
     * @returns {string|null} JWT Token字符串，如果不存在返回null
     * 
     * @description 从localStorage读取保存的JWT Token
     * 
     * 设计考虑：
     * 使用localStorage而不是sessionStorage
     * 原因：localStorage在浏览器关闭后仍保留，实现"记住登录"功能
     */
    getToken() {
        return localStorage.getItem('token');
    }

    /**
     * 设置Token
     * 
     * @method setToken
     * @param {string} token - JWT Token字符串
     * @returns {void}
     * 
     * @description 将JWT Token保存到localStorage
     * 
     * 使用场景：
     * - 用户登录成功后保存Token
     * - 用户注册成功后保存Token
     */
    setToken(token) {
        localStorage.setItem('token', token);
    }

    /**
     * 清除Token
     * 
     * @method clearToken
     * @returns {void}
     * 
     * @description 从localStorage删除Token
     * 
     * 使用场景：
     * - 用户退出登录
     * - Token过期需要重新登录
     */
    clearToken() {
        localStorage.removeItem('token');
    }

    // ==================== 错误处理方法 ====================

    /**
     * 错误信息中文映射
     * 
     * @method translateError
     * @param {string} message - 英文错误消息
     * @returns {string} 中文错误消息
     * 
     * @description 将后端返回的英文错误消息转换为中文，提升用户体验
     * 
     * @example
     * translateError('User not found') // 返回: '用户不存在'
     * translateError('Invalid password') // 返回: '密码错误'
     * 
     * 设计思路：
     * 1. 使用对象映射，快速查找对应的中文
     * 2. 如果没有对应的中文，返回原消息
     * 3. 便于维护和扩展（添加新的错误消息映射）
     */
    translateError(message) {
        const errorMap = {
            'User not found': '用户不存在',
            'Invalid password': '密码错误',
            'Username already exists': '用户名已存在',
            'Email already exists': '邮箱已存在',
            'Invalid token': 'Token无效',
            'Token expired': 'Token已过期',
            'Unauthorized': '未授权',
            'Forbidden': '禁止访问',
            'Not found': '未找到',
            'Internal server error': '服务器错误',
            'Network error': '网络错误',
            'Failed to fetch': '网络连接失败，请检查后端是否启动'
        };
        
        // 查找对应的中文，如果没有则返回原消息
        return errorMap[message] || message;
    }

    // ==================== HTTP请求核心方法 ====================

    /**
     * 通用HTTP请求方法
     * 
     * @method request
     * @async
     * @param {string} url - 相对URL路径（如：'/auth/login'）
     * @param {object} options - Fetch API选项
     * @param {string} options.method - HTTP方法（GET/POST/PUT/DELETE）
     * @param {object} options.headers - 自定义请求头
     * @param {string} options.body - 请求体（JSON字符串）
     * 
     * @returns {Promise<object>} API响应数据
     * @throws {Error} 请求失败或网络错误
     * 
     * @description 封装Fetch API，自动处理认证、错误等
     * 
     * @example
     * // GET请求
     * const data = await api.request('/books', { method: 'GET' });
     * 
     * // POST请求
     * const data = await api.request('/auth/login', {
     *   method: 'POST',
     *   body: JSON.stringify({ username: 'test', password: '123456' })
     * });
     * 
     * 功能特点：
     * 1. 自动添加Content-Type: application/json
     * 2. 自动添加Authorization头（如果有Token）
     * 3. 自动解析JSON响应
     * 4. 统一错误处理（翻译错误消息）
     * 5. 记录错误日志到控制台
     * 
     * 设计思路：
     * 1. 动态读取Token（每次请求时获取最新Token）
     * 2. 使用...展开运算符合并options
     * 3. response.ok判断HTTP状态码是否为2xx
     * 4. 统一的错误抛出，便于上层catch处理
     */
    async request(url, options = {}) {
        // 1. 构建请求头
        const headers = {
            'Content-Type': 'application/json',  // 默认JSON格式
            ...options.headers                   // 合并自定义头
        };

        // 2. 每次请求时动态读取token
        // 设计考虑：token可能在运行时更新，动态读取确保使用最新值
        const token = this.getToken();
        if (token) {
            // 添加Authorization头，格式：Bearer <token>
            headers['Authorization'] = `Bearer ${token}`;
        }

        // 3. 合并请求配置
        const config = {
            ...options,   // 包含method、body等
            headers       // 覆盖headers
        };

        try {
            // 4. 发送HTTP请求
            // 完整URL = API_BASE_URL + url
            // 例如：http://localhost:3000/api + /auth/login
            const response = await fetch(`${API_BASE_URL}${url}`, config);
            
            // 5. 解析JSON响应
            const data = await response.json();

            // 6. 检查HTTP状态码
            // response.ok为true表示状态码为2xx（成功）
            if (!response.ok) {
                // 请求失败，翻译错误消息并抛出
                const errorMessage = this.translateError(data.message || '请求失败');
                throw new Error(errorMessage);
            }

            // 7. 返回响应数据
            return data;
            
        } catch (error) {
            // 8. 错误处理
            // 记录错误到控制台，便于调试
            console.error('API请求错误:', error);
            
            // 翻译错误信息（如果有）
            if (error.message) {
                error.message = this.translateError(error.message);
            }
            
            // 重新抛出错误，让调用方处理
            throw error;
        }
    }

    // ==================== 用户认证模块 ====================

    /**
     * 用户认证API模块
     * 
     * @property {object} auth - 认证相关API集合
     * @property {function} auth.register - 用户注册
     * @property {function} auth.login - 用户登录
     * @property {function} auth.setPIN - 设置PIN码
     * @property {function} auth.verifyPIN - 验证PIN码
     * @property {function} auth.checkPINStatus - 检查PIN状态
     * 
     * @description 使用getter模式返回API方法对象
     * 
     * 使用示例：
     * const api = new API();
     * await api.auth.register('username', 'password', 'nickname');
     * await api.auth.login('username', 'password');
     * 
     * 设计模式：
     * - 使用getter返回对象，实现模块化分组
     * - 使用self保存this引用，避免this指向问题
     * - 每个方法都是async函数，返回Promise
     */
    get auth() {
        const self = this;  // 保存this引用
        return {
            /**
             * 用户注册
             * 
             * @method register
             * @async
             * @param {string} username - 用户名
             * @param {string} password - 密码
             * @param {string} nickname - 昵称（选填）
             * @returns {Promise<object>} 注册结果（包含user_id、token等）
             * 
             * @example
             * const result = await api.auth.register('zhangsan', '123456', '张三');
             * // result.data.token
             */
            register: async (username, password, nickname) => {
                return self.request('/auth/register', {
                    method: 'POST',
                    body: JSON.stringify({ username, password, nickname })
                });
            },

            /**
             * 用户登录
             * 
             * @method login
             * @async
             * @param {string} username - 用户名
             * @param {string} password - 密码
             * @returns {Promise<object>} 登录结果（包含user_id、token等）
             * 
             * @description 登录成功后自动保存Token到localStorage
             * 
             * @example
             * const result = await api.auth.login('zhangsan', '123456');
             * // 自动保存token
             */
            login: async (username, password) => {
                const result = await self.request('/auth/login', {
                    method: 'POST',
                    body: JSON.stringify({ username, password })
                });
                
                if (result.data.token) {
                    self.setToken(result.data.token);
                }
                
                return result;
            },

            // 设置PIN
            setPIN: async (pin) => {
                return self.request('/auth/pin/set', {
                    method: 'POST',
                    body: JSON.stringify({ pin })
                });
            },

            // 验证PIN
            verifyPIN: async (pin) => {
                return self.request('/auth/pin/verify', {
                    method: 'POST',
                    body: JSON.stringify({ pin })
                });
            },

            // 检查PIN状态
            checkPINStatus: async () => {
                return self.request('/auth/pin/status');
            },
            
            // 别名方法
            getPINStatus: async () => {
                return self.request('/auth/pin/status');
            }
        };
    }

    // ==================== 账本管理模块 ====================

    /**
     * 账本管理API模块
     * 
     * @property {object} books - 账本相关API集合
     * @property {function} books.getList - 获取账本列表
     * @property {function} books.create - 创建账本
     * @property {function} books.generateShareCode - 生成分享码
     * @property {function} books.join - 加入账本
     * @property {function} books.getMembers - 获取成员列表
     * @property {function} books.delete - 删除账本
     * 
     * @description 账本CRUD操作和分享功能
     * 
     * 使用示例：
     * const books = await api.books.getList();
     * await api.books.create({ book_name: '家庭账本', book_type: 'family' });
     */
    get books() {
        const self = this;
        return {
            // 获取账本列表
            getList: async () => {
                return self.request('/books');
            },

            // 创建账本
            create: async (bookData) => {
                return self.request('/books', {
                    method: 'POST',
                    body: JSON.stringify(bookData)
                });
            },

            // 生成分享码
            generateShareCode: async (bookId) => {
                return self.request(`/books/${bookId}/share`, {
                    method: 'POST'
                });
            },

            // 加入账本
            join: async (shareCode) => {
                return self.request('/books/join', {
                    method: 'POST',
                    body: JSON.stringify({ share_code: shareCode })
                });
            },

            // 获取成员列表
            getMembers: async (bookId) => {
                return self.request(`/books/${bookId}/members`);
            },

            // 删除账本
            delete: async (bookId) => {
                return self.request(`/books/${bookId}`, {
                    method: 'DELETE'
                });
            },
            
            // 别名方法
            list: async () => {
                return self.request('/books');
            }
        };
    }

    // ==================== 记录管理模块 ====================

    /**
     * 收支记录API模块
     * 
     * @property {object} records - 记录相关API集合
     * @property {function} records.getList - 获取记录列表（支持筛选）
     * @property {function} records.add - 添加记录
     * @property {function} records.update - 更新记录
     * @property {function} records.delete - 删除记录
     * 
     * @description 记录CRUD操作，支持筛选、分页等
     * 
     * 使用示例：
     * const records = await api.records.getList({ book_id: 1, type: 'expense' });
     * await api.records.add({ book_id: 1, type: 'expense', amount: 50, category: 'food' });
     */
    get records() {
        const self = this;
        return {
            // 获取记录列表（支持筛选参数）
            getList: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/records?${query}`);
            },

            // 添加记录
            add: async (recordData) => {
                return self.request('/records', {
                    method: 'POST',
                    body: JSON.stringify(recordData)
                });
            },

            // 编辑记录
            update: async (recordId, recordData) => {
                return self.request(`/records/${recordId}`, {
                    method: 'PUT',
                    body: JSON.stringify(recordData)
                });
            },

            // 删除记录
            delete: async (recordId) => {
                return self.request(`/records/${recordId}`, {
                    method: 'DELETE'
                });
            },
            
            // 别名方法
            list: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/records?${query}`);
            }
        };
    }

    // ==================== 统计分析模块 ====================

    /**
     * 数据统计API模块
     * 
     * @property {object} stats - 统计相关API集合
     * @property {function} stats.getOverview - 获取统计概览
     * @property {function} stats.getMonthly - 获取月度统计（图表）
     * @property {function} stats.getCategoryChart - 获取分类统计（饼图）
     * 
     * @description 提供各种维度的数据统计和图表数据
     * 
     * 使用示例：
     * const overview = await api.stats.getOverview({ book_id: 1 });
     * const monthlyData = await api.stats.getMonthly({ book_id: 1 });
     * const categoryData = await api.stats.getCategoryChart({ book_id: 1, type: 'expense' });
     */
    get stats() {
        const self = this;
        return {
            // 获取概览统计
            getOverview: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/stats/overview?${query}`);
            },
            
            // 📊 新增：获取月度统计数据（网页版图表）
            getMonthly: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/stats/chart/monthly?${query}`);
            },
            
            // 📊 新增：获取分类统计数据（用于饼图）
            getCategoryChart: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/stats/chart/category?${query}`);
            }
        };
    }

    // 预算管理
    get budgets() {
        const self = this;
        return {
            list: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/budgets?${query}`);
            },
            create: async (budgetData) => {
                return self.request('/budgets', {
                    method: 'POST',
                    body: JSON.stringify(budgetData)
                });
            },
            update: async (id, budgetData) => {
                return self.request(`/budgets/${id}`, {
                    method: 'PUT',
                    body: JSON.stringify(budgetData)
                });
            },
            delete: async (id) => {
                return self.request(`/budgets/${id}`, {
                    method: 'DELETE'
                });
            },
            getAlerts: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/budgets/alerts?${query}`);
            }
        };
    }

    // 快捷记账
    get quickItems() {
        const self = this;
        return {
            list: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/quick-items?${query}`);
            },
            create: async (itemData) => {
                return self.request('/quick-items', {
                    method: 'POST',
                    body: JSON.stringify(itemData)
                });
            },
            use: async (id, data = {}) => {
                return self.request(`/quick-items/${id}/use`, {
                    method: 'POST',
                    body: JSON.stringify(data)
                });
            },
            update: async (id, itemData) => {
                return self.request(`/quick-items/${id}`, {
                    method: 'PUT',
                    body: JSON.stringify(itemData)
                });
            },
            delete: async (id) => {
                return self.request(`/quick-items/${id}`, {
                    method: 'DELETE'
                });
            }
        };
    }

    // 高级功能
    get advanced() {
        const self = this;
        return {
            // 财务目标
            getGoals: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/advanced/goals?${query}`);
            },
            createGoal: async (goalData) => {
                return self.request('/advanced/goals', {
                    method: 'POST',
                    body: JSON.stringify(goalData)
                });
            },
            updateGoalProgress: async (id, current_amount) => {
                return self.request(`/advanced/goals/${id}/progress`, {
                    method: 'PUT',
                    body: JSON.stringify({ current_amount })
                });
            },
            
            // 定期账单
            getRecurringBills: async () => {
                return self.request('/advanced/recurring-bills');
            },
            createRecurringBill: async (billData) => {
                return self.request('/advanced/recurring-bills', {
                    method: 'POST',
                    body: JSON.stringify(billData)
                });
            },
            createRecordFromBill: async (billId) => {
                return self.request(`/advanced/recurring-bills/${billId}/create-record`, {
                    method: 'POST'
                });
            },
            
            // 留言板
            getComments: async (book_id) => {
                return self.request(`/advanced/comments?book_id=${book_id}`);
            },
            addComment: async (commentData) => {
                return self.request('/advanced/comments', {
                    method: 'POST',
                    body: JSON.stringify(commentData)
                });
            },
            
            // 成就系统
            getAchievements: async () => {
                return self.request('/advanced/achievements');
            },
            checkAchievements: async () => {
                return self.request('/advanced/achievements/check', {
                    method: 'POST'
                });
            },
            
            // 智能分类建议
            getCategorySuggest: async (keyword) => {
                return self.request(`/advanced/category-suggest?keyword=${encodeURIComponent(keyword)}`);
            },
            learnCategory: async (keyword, category) => {
                return self.request('/advanced/category-suggest/learn', {
                    method: 'POST',
                    body: JSON.stringify({ keyword, category })
                });
            },
            
            // 分析报告
            generateReport: async (book_id, report_type) => {
                return self.request('/advanced/analysis/generate', {
                    method: 'POST',
                    body: JSON.stringify({ book_id, report_type })
                });
            },
            getReports: async (report_type) => {
                return self.request(`/advanced/analysis/reports?report_type=${report_type || ''}`);
            },
            
            // 数据备份
            createBackup: async () => {
                const response = await fetch(`${API_BASE_URL}/advanced/backup`, {
                    method: 'POST',
                    headers: {
                        'Authorization': `Bearer ${self.getToken()}`
                    }
                });
                
                if (!response.ok) throw new Error('备份失败');
                
                const blob = await response.blob();
                const url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `backup_${Date.now()}.json`;
                document.body.appendChild(a);
                a.click();
                window.URL.revokeObjectURL(url);
                document.body.removeChild(a);
            },
            
            // 排行榜
            getLeaderboard: async (book_id) => {
                return self.request(`/advanced/leaderboard?book_id=${book_id}`);
            }
        };
    }

    // ==================== 游戏化功能模块 ====================

    /**
     * 游戏化API模块
     * 
     * @property {object} gamification - 游戏化相关API集合
     * @property {function} gamification.getAchievements - 获取成就列表
     * @property {function} gamification.checkAchievements - 检查并解锁成就
     * @property {function} gamification.getLevel - 获取用户等级
     * @property {function} gamification.addExp - 增加经验值
     * @property {function} gamification.updateStats - 更新统计数据
     * @property {function} gamification.getGameLeaderboard - 获取排行榜
     * 
     * @description 游戏化系统（成就、等级、积分）
     * 
     * 特殊处理：
     * 游戏化功能是可选的，如果后端未启用，不影响核心功能
     * 使用safeGameRequest包装器静默处理错误
     * 
     * 使用示例：
     * const achievements = await api.gamification.getAchievements();
     * const level = await api.gamification.getLevel();
     */
    get gamification() {
        const self = this;
        
        /**
         * 游戏化功能的安全请求包装器
         * 
         * @function safeGameRequest
         * @async
         * @param {string} url - API路径
         * @param {object} options - 请求选项
         * @returns {Promise<object>} API响应或错误对象
         * 
         * @description 包装游戏化API请求，静默处理错误
         * 
         * 设计思路：
         * 1. 游戏化功能是增强功能，不是核心功能
         * 2. 如果后端未启用游戏化功能，不应影响主要功能
         * 3. catch错误后返回友好的错误对象，而不是抛出异常
         * 4. 只在控制台输出提示，不打断用户操作
         */
        const safeGameRequest = async (url, options = {}) => {
            try {
                return await self.request(url, options);
            } catch (error) {
                // 静默处理游戏化功能的错误
                // 这些功能是可选的，不应该影响核心功能
                console.log('游戏化功能未启用（这是正常的）');
                return { code: 500, data: null, error: '游戏化功能未启用' };
            }
        };
        
        return {
            // 暴露安全请求包装器，供外部使用
            safeGameRequest,
            
            // 成就系统
            getAchievements: async () => {
                return safeGameRequest('/gamification/achievements');
            },
            checkAchievements: async () => {
                return safeGameRequest('/gamification/achievements/check', {
                    method: 'POST'
                });
            },
            
            // 等级系统
            getLevel: async () => {
                return safeGameRequest('/gamification/level');
            },
            addExp: async (exp) => {
                return safeGameRequest('/gamification/level/add-exp', {
                    method: 'POST',
                    body: JSON.stringify({ exp })
                });
            },
            updateStats: async () => {
                return safeGameRequest('/gamification/update-stats', {
                    method: 'POST'
                });
            },
            
            // 排行榜
            getGameLeaderboard: async () => {
                return safeGameRequest('/gamification/leaderboard');
            }
        };
    }

    // 扩展功能
    get features() {
        const self = this;
        return {
            // 标签
            getTags: async () => {
                return self.request('/features/tags');
            },
            createTag: async (tagData) => {
                return self.request('/features/tags', {
                    method: 'POST',
                    body: JSON.stringify(tagData)
                });
            },
            deleteTag: async (id) => {
                return self.request(`/features/tags/${id}`, {
                    method: 'DELETE'
                });
            },
            
            // 设置
            getSettings: async () => {
                return self.request('/features/settings');
            },
            updateSettings: async (settings) => {
                return self.request('/features/settings', {
                    method: 'PUT',
                    body: JSON.stringify(settings)
                });
            },
            
            // 趋势分析
            getTrends: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/features/trends?${query}`);
            },
            getCompare: async (params = {}) => {
                const query = new URLSearchParams(params).toString();
                return self.request(`/features/compare?${query}`);
            },
            
            // 数据导出
            exportData: async (params = {}) => {
                try {
                    const query = new URLSearchParams(params).toString();
                    const response = await fetch(`${API_BASE_URL}/features/export?${query}`, {
                        headers: {
                            'Authorization': `Bearer ${self.getToken()}`
                        }
                    });
                    
                    if (!response.ok) {
                        // 尝试获取错误信息
                        const contentType = response.headers.get('content-type');
                        if (contentType && contentType.includes('application/json')) {
                            const errorData = await response.json();
                            throw new Error(errorData.message || '导出失败');
                        } else {
                            throw new Error('导出失败，状态码：' + response.status);
                        }
                    }
                    
                    const blob = await response.blob();
                    const url = window.URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = `预算导出_${Date.now()}.csv`;
                    document.body.appendChild(a);
                    a.click();
                    window.URL.revokeObjectURL(url);
                    document.body.removeChild(a);
                    // 成功提示已在main.js中处理
                } catch (error) {
                    console.error('导出失败:', error);
                    throw error; // 抛出错误让main.js处理
                }
            },
            
            // 账本对比
            getBooksCompare: async () => {
                return self.request('/features/books-compare');
            }
        };
    }
}

// 创建API实例并导出
const api = new APIClient();

// 为了兼容性，同时导出大写的API对象（包含工具方法）
const API = {
    baseURL: API_BASE_URL,
    
    // 检查是否已登录
    isLoggedIn: () => {
        return !!localStorage.getItem('token');
    },
    
    // 获取token
    getToken: () => {
        return localStorage.getItem('token');
    },
    
    // 通用GET请求
    get: async (url) => {
        return api.request(url);
    },
    
    // 通用POST请求
    post: async (url, data) => {
        return api.request(url, {
            method: 'POST',
            body: JSON.stringify(data)
        });
    },
    
    // 通用DELETE请求
    delete: async (url) => {
        return api.request(url, {
            method: 'DELETE'
        });
    }
};

